/**
 * @file hal_gamepad.cpp
 * @author Forairaaaaa
 * @brief
 * @version 0.1
 * @date 2023-11-07
 *
 * @copyright Copyright (c) 2023
 *
 */
#include <mooncake.h>
#include <Arduino.h>
#include <FS.h>
#include <LittleFS.h>
#include "../hal_rachel.h"
#include "../hal_config.h"
#include <ArduinoJson.h>

void HAL_Rachel::_fs_init()
{
    spdlog::info("fs init");
    HAL_LOG_INFO("fs init");

    // File system
    if (!LittleFS.begin(true))
    {
        spdlog::error("LittleFS init failed!");
        popFatalError("LittleFS init failed");
    }
}

static const String _system_config_path = "/_sys/cfg.json";

void HAL_Rachel::loadSystemConfig()
{
    spdlog::info("start loading config from fs");

    // Check exist
    if (!LittleFS.exists(_system_config_path))
    {
        spdlog::warn("{} not exist", _system_config_path.c_str());
        saveSystemConfig();
        return;
    }

    // Open file
    File config_file = LittleFS.open(_system_config_path);
    if (!config_file)
        popFatalError("打开配置文件失败");

    // Parse json
    DynamicJsonDocument doc(4096);
    deserializeJson(doc, config_file);

    // Copy configs
    _config.brightness = doc["brightness"];
    _config.volume = doc["volume"];
    const char *ssid = doc["wifi_ssid"];
    if (ssid)
    {
        spdlog::info("ssid exist");
        strcpy(_config.wifi_ssid, ssid);
    }
    else
    {
        spdlog::info("no ssid exist");
        saveSystemConfig();
        ESP.restart();
    }

    _config.baud_uart = doc["baud_uart"];
    _config.baud_can = doc["baud_can"];
    _config.file_max_size = doc["file_max_size"];
    _config.add_time_to_log_uart = doc["add_time_to_log_uart"];
    _config.add_time_to_log_can = doc["add_time_to_log_can"];
    _config.rec_uart_flag = doc["rec_uart_flag"];
    _config.rec_can_flag = doc["rec_can_flag"];

    if (_config.file_max_size == 0 || _config.baud_uart == 0 || _config.baud_can == 0)
    {
        _config.file_max_size = 10;
        _config.baud_uart = 115200;
        _config.baud_can = 1000;
        saveSystemConfig();
        ESP.restart();
    }

    config_file.close();
}

void HAL_Rachel::saveSystemConfig()
{
    spdlog::info("start saving config to fs");

    // Open file
    File config_file = LittleFS.open(_system_config_path, FILE_WRITE, true);
    if (!config_file)
        popFatalError("创建配置文件失败");

    // Create json
    DynamicJsonDocument doc(4096);
    doc["brightness"] = _config.brightness;
    doc["volume"] = _config.volume;
    doc["wifi_ssid"] = _config.wifi_ssid;
    doc["baud_uart"] = _config.baud_uart;
    doc["baud_can"] = _config.baud_can;
    doc["file_max_size"] = _config.file_max_size;
    doc["add_time_to_log_uart"] = _config.add_time_to_log_uart;
    doc["add_time_to_log_can"] = _config.add_time_to_log_can;
    doc["rec_uart_flag"] = _config.rec_uart_flag;
    doc["rec_can_flag"] = _config.rec_can_flag;

    // Save file
    if (serializeJson(doc, config_file) == 0)
        popFatalError("写入配置文件失败");

    config_file.close();
}

void HAL_Rachel::_log_out_system_config()
{
    spdlog::info("system config:");
    spdlog::info(" - brightness: {}", _config.brightness);
    spdlog::info(" - volume: {}", _config.volume);
    spdlog::info(" - wifiSsid: {}", _config.wifi_ssid);
    spdlog::info(" - baud_uart: {}", _config.baud_uart);
    spdlog::info(" - baud_can: {}", _config.baud_can);
    spdlog::info(" - file_max_size: {}", _config.file_max_size);
    spdlog::info(" - add_time_to_log_uart: {}", _config.add_time_to_log_uart);
    spdlog::info(" - add_time_to_log_can: {}", _config.add_time_to_log_can);
    spdlog::info(" - rec_uart_flag: {}", _config.rec_uart_flag);
    spdlog::info(" - rec_can_flag: {}", _config.rec_can_flag);
}

void HAL_Rachel::_system_config_init()
{
    HAL_LOG_INFO("load config from fs");
    loadSystemConfig();

    HAL_LOG_INFO("update device from config");
    updateSystemFromConfig();

    _log_out_system_config();
}
